(Caveat lector: these TL notes are just a rant, added to whenever something became frustrating.  Besides the script, many focus on the underlying scripting systems--note the plural--used to present them.)

First, a note before the notes:
  Somehow I wasn't aware of the famous-ish Puyo Nexus translation until near the end of my own, which was done sort of backwards (hard stuff to easy) after months of lead-in hacking stuff.  Shame really.  Would have been much easier to just pirate it wholesale.  A full TLC would have been a good idea and still is, but didn't happen.
  A shortlist of pirated script:
  *) If Draco's story seems suspiciously similar that's because it is.
  *) The tutorial is nearly 1::1.  Might have taken the "Rules" image as well?  Hard to say, since image layout works in a fundamentally different way.
  *) Victory statements, though many (most?) did not survive TLC.  For example, Lagnus is trying to party up, not party down ;*)  None are skipped in this version either.
  *) Maybe that congratulations text at the end of the Tournament?  Honestly not sure, with how much editing went into getting it to work.

Audio was added as an afterthought, first to the endings (over the course of a couple days) and later to Story Mode (over the course of a couple months).  This was so nightmarish it gets its own little subsection below.

Plus one quick apology:
  The title screen puyos are a bit creepy.  If this were an official release I'd call somebody from the art department to make the tops of the "o"s wiggly instead, but since I +am+ the art department and am a couple degrees short of competence, you get what you get.  Could be more jelly-like too.  It doesn't have much depth.


Localization Notes:
  I, unashamedly, made several necessary changes due to memory restrictions and several more unnecessary ones to fit personal aesthetics.  If you feel this ruins everything and the game is now unplayable, obviously you're completely right.  Don't waste your time not playing.

  The primary difference between this title and its PC counterpart (once you factor out endianess and missing content, of course) has to do with image storage.  This version does not use arbitrary sizes, instead referring to a table of fixed tile sizes.  These are all multiples of eight, eliminating the need for padding out rows when moving them to the RDP.  This reduces image entries to a mere 4 bytes each, and each can identify an array of 7x31 of like-sized tiles.  (Pretty sure the PC version also has a "tile" size each image is laid in and the source image can be an arbitrary size, but moving on.)
  The caveat here is that, on the back end, each set tile is also generating at least one set of display lists.  Large tile count--a large amount of text, for instance--can overflow the display list buffer and prevent further images from being displayed.  The worst case is the Tournament Options screen, where memory mismanagement led to a situation where longer string lengths will cut off text.  "# Matches" just barely fits under the cap with bytes to spare, necessitating the same change on the main Options menu.  Another problematic one prevented expanding the "practice mode" message's width without losing Schezo's name.
  It's usually much easier to shave a pixel or two off an image than to push it a size larger and deal with alignment issues or tiling.  On the plus side, this serves a particularly clever means of justifying radical image changes.  There's a number of them, and all are subsequently justified even when it's all a ruse.

  Another situation is that individual image spans are copied into a buffer when the display lists are handled, and that buffer isn't necessarily large enough for the entire image span.  In those cases, the thing can be split into smaller blocks and displayed without an issue.  It's absurd but it works.  An excellent example are the cabs in the arcade version.  Ten 160x16 spans doesn't work.  Twenty 160x8 spans do.  It's magic.
  Tournament mode suffered a number of band-aid patches in this port and one of those applies to the "Congratulations" message at the end, replaced with text.  This may have been because if you were to set it as a tile with its normal width of 208 you'd cause a memspan overflow as described above.  As a workaround, it was expanded slightly and subdivided into seven 32x32 tiles--seven being the most you can place horizontally.  It no longer renders "text"; the image is displayed solely from the scripting microcode.
  For fun, lifted the difficulty limitation on Tournaments.  Also added a specific message for semifinal rounds as opposed to the rounds before them.  Also squashed the tiling bug for the scrolling message behind that end graphic, changed the default for watching AI matches off, and squashed half a dozen memory overruns.  Didn't manage to fix the scaling thing though, which apparently lies in the printer and not the zoom itself.

  The primary font--the one in bank 33 used for dialog text--is now a fully variable-width font.  The text writer catches that bank in particular and ignores the "tile size" set by text commands, etc.  Instead, all images in the bank are offset, and the start of the image portion of the bank has a width table.  "True" spaces use one size, fullwidth spaces another, and a special entry is set to an intermediate size as a workaround for setting the default widths used with the number writer text command.
  In addition, all text banks have a single-byte couplet method available for use with the first 126 characters.  In this mode, index zero acts as a space.  It provides copious additional space, all of which is gobbled up by extending features like those animated gradient fonts in the main menu, the wiggly gradient font on the hi-score entry page, and the gradient font used for character names in story mode.
  Did I mention "text" is a sub-scripting type of the scripting microcode?  It's also indistinguishable from any other type of image display.  Parts of that VWF hack apply to *all* images.  Yeah, this game's "fun".

  Due to filesizes, it wasn't practical to pre-generate the gradient text used for story mode character names.  These use a "fake" VWF, setting each tile and manipulating spacing as required.  Not perfect, but not horrible.  The style was changed to match what is now used on the main menus.  It was remarkably easier to print them in reverse order, right to left, using negative spacing.
  The scripting for the menu gradient text was modified to account for the additional characters drawn to screen instead of using the compacted ones from the PC version or BSing it like the Korean PC version.  It may have been possible to save more space here by using a table, an index, and allowing the same code to pull each of the characters and their positions.  Honestly, that's a much bigger hassle than just doing it this way.  Some room was saved JALing to recycled components at least.
  Ditto the last line, but replace "menu" with "hi-score".  The scripting is nearly identical.

  Two text scripting commands were added in place of NOPs.  One is an alternate newline that advances a line and a half (a dirty hack to solve the problems caused by the text writer rewrite), and the other offsets only the x position.  In addition, all commands that accepted a pointer no longer require word alignment padding.  LWL & LWR were made for a reason ;*)
  A flag was added to the JAL conditional list command to use the current text object instead of the general value table.  If FF1D didn't exist, the same could have been done to FF0D to make it identical in operation.
  Major amounts of space were saved by clipping out common snippets of code from dialog, creating a subfunction out of them, then using a JAL text command.  The start and end of virtually every line of character dialog is borrowed from a single source.  Practical result is that every character victory message is present in here, including the ones excised from Puyo Nexus's PC version thanks to its memory constraints.  (Although if they used the JAL trick and didn't set fake spacings for every character even when they don't change they probably could have fit them...)

  There's some specialized scripting that writes the text used in the endings.  Before, it expected a flag for which side of the screen it would appear on, then print fourteen characters in two columns.  Always fourteen.  Ten of those were usually spaces.
  That had to go.  The routine was rewritten to read arbitrarily long strings and utilizes a number of exploits.  It now starts with an x,y position, followed by image + spacing pairs.  Spacing of 0 ends the string, and spacing above 31 applies a newline with optional left or right realignment.
  Firstly, x,y positions are technically longs (fixed-point ints), but the upper HW is the only relevant part.  However, to add and store a HW result you need two HW sources, and the offset values are all bytes.  By loading it into a variable first it gets around the target limitation.
  The timer command is designed to be reentrant, and the timer value is part of the image instance.  In the case the timer isn't set it reads the value from the command, but when set already it figures it's still just in the timer loop.  That means you can set the timers manually instead of relying on a series of incremental timer values, and that's important if you can't predict a string's maximum length.  Each timer is progressively two higher than the last to provide the wipe in, but each character is a generated instance from a master.  Timer values aren't preserved between instances, but there is a value that isn't used by this printer that can be used as temporary storage and pushed into the timer target.
  Iterating through the source string can be done by modifying the initial loaded pointer.  It also happens to be stored in the instance, and the setup is only run once.

  For some daft reason the entire first column of the loaded palette table is always alpha and all other entries--irregardless of their source's alpha flag--are always visible.  It's a weird conceptual choice when you virtually always load in blocks of hundreds of colors, and even weirder since you can load as few as one color into an arbitrary slot on the table.  Otherwise, the palette loader has a lot of unused functionality.  It can channel rebalance either staticly or dynamicly and indicies can be relative to the current index.

  Debug features were not restored.  The debug menus and their interfaces are really just script commands, and writing yet another giant block of their scripting stuff and hooking it into +everything+ would be about as much fun as translating this game into cuneiform.
  They're formatted suspiciously like the ST-V version.  The font is likely the 8x8 one found in bank 6 of the PC version used for the credits, coinage, and insert coin messages.  It could be any random 8x8 font though.  It isn't terribly difficult to get printing again through their general tile application thingy using 80005670, though it's likely just the plain-jane debug print thing from the SDK or printing directly to the framebuffer.  There's only four functions and one just spits out a screen position for a given pixel.  The only one requiring effort is the numeral printer.

  One debug feature was restored and then removed.  There's a monochrome puyo that will display when you try to apply a tile using an unloaded resource bank.  You don't notice this because 1) they always load their resource banks properly and 2) because the palette is blank.  Setting 0x4EDFA to FFFF allows it to be seen on the offchance you butcher a resource loader someplace, like I did when mixing up font banks.

  Carbuncle's "Gu!" really is supposed to go offscreen.  Aesthetics and all.

  "Blow Arle straight to China!" is technically a misreading.

  "Death from above!" is punchier.  Was a toss-up with "Death from the sky!"

  In Rulue & Schezo one line combined some dialog from a suppressed line that's still present in memory.  There's a number of those throughout in fact.


Audio...
  For the sake of complete disclosure, know that the expanded audio is done in the hackiest imaginable way.  Apologies to those who care.  Don't make direct eye contact with the code and you'll be fine.
  First, as a bit of background, know that no two official releases share the same audio.
    The arcade unit, based off the Saturn, split BGM and SFX.  Although story mode lacks voice, there are SFX and fully-voiced endings.  These are stored as AIFFs, each a 16bit PCM stream ranging from 18000 Hz to 44100 Hz.
    Saturn merged the BGM and voice and saved a different AIFF for each.  Audio consists of 16bit PCMs at 22050 Hz in stereo, pretty much in entirety.  There's some pitch differences in voice compared to other versions.
    Both PC versions divided the BGM and voice, storing each sample as 16bit PCM at 11025 Hz.  The proprietary format they use is basically the second part of a wav file and its data.
    PSX also splits the voice out and store it in their proprietary sequence format except most samples are 22050 Hz, with the occasional 44100 Hz and 11025 Hz thrown in.  No joke, pitch in PSX samples is remarkably better than PC, though some of Schezo's route is at least 10dB lower than it should be.
    The N64, like the arcade, lacks story mode voice.  Most SFX are 11025 Hz, but some like the "Puyo Puyo Sun" cheer on the title screen are 22050 Hz.  Placeholders for voice triggers remain in the endings, but not in story mode.

  It's not like full voice can't fit on a cart (obviously), just that you'd have to grow to the next chip size up and Compile is cheap.
  As far as Japanese or Korean versions, using 11025 Hz samples cleanly fits within a 12MB ROM.  The base English patch is significantly larger so a 16MB ROM was always a necessity.  After initially stealing the PC audio and finding it inconsistent, everything was reimported from the PSX and arcade versions--without checking audio levels.  Then everything was reimported after normalizing the top end but some of Schezo's stuff was inconsistent (and Kodomo 2 was...different...compared to all other sources) so parts of his route intermix 11k and 22k samples.  A couple of Draco's lines are 44k.  It's a smorgasbord of sample rates.  Six or so imports later, the audio bank was finalized and now consumes appoximately 2/3 of the total space.

  The bizarre thing about the N64 audio implementation is that they effectively hack the soundtables during runtime.  These use the standard types provided by the SGI variant of the SDK (yes, the Win version was different), but what they do is hook the sequence loader, use a table to look up the sounds it will use, use another table to shift those into soundbank+instrument indicies, then use another table to override the velocities, frequency keys, panning, durations, etc. in the soundbank by overwriting them.  Bonkers.  In case you're wondering, this is the reason SubDrag's N64SoundTools don't support importing into this title.
  End result is that to add all the story mode voice in means you have to either slice out all the audio code and replace it, or magically find room for ~230 additional entries of all that extraneous stuff which must be present in memory at all times.  If you cruch numbers you'll see that there's less than 4KB of allocated space for additional audio and you'll need a minimum of three times that for full voice.
  So, you'll find these audio files are more redundant than usual and reducing the redundancy nets about as much room as is necessary for the full table, but that's out due to the overwriting trick they're using for who knows what reason.  Recycling predictors didn't suffice for the amount of room required and they did a fair amount of that already.  TLB witchcraft can't be applied alongside the overrides.  If there were only one table of overrides that would be fine, but there aren't.  It could be cut out, but requires applying the changes to the audio file and duplicating a few entries, then rehooking them in other cases and modifying the sequences.  In either case the base filesizes grow.  Predicted filesizes were way too close to the available memory limit.  Aegh...
  In the end, the banks were split by hand into two opposing memory regions after a pocket of unused memory was found below one of the buffers.  It's a hack--a hack that works ;*)

  Hooking audio in requires writing the triggers back into the script.  What makes this "fun" is that scripting commands changed slightly between versions (not to mention the script itself).  The additional argument for music is still read, but it isn't used.  Of the multiple different methods of calling audio in PC only handful still work on N64, with different arguments and setup.  Two additional methods were added though, but one of them is limited to 256 sounds.  The other, a text command (or two?) that triggers audio, isn't usable thanks to the way that subroutines are implemented.  The sound won't be played unless the subroutine returns, but a return also triggers the window to close.  So, fun stuff, the audio isn't played until the subroutine restarts--when you print the next like of text.
  In some cases, it made more sense to string together a single sequence that played multiple individual sounds instead of inserting short waits between multiple calls.
  Timings for lines though followed the arcade version, not other voiced versions.  Delays need to be added, modified, or moved in order for audio to play its full length without overrunning the next line but without affecting the triggers to start and stop animations.
  Long story short, after much unmuddling and a bit of hacking, the story scripts were mutilated to insert audio at approximately the correct points.

  One lucky thing though is that the endings only commented out the audio triggers.  They didn't remove them.  Maybe they considered voicing that and backed off, or based this off the arcade release?  Including them pushes filesizes very close to the limit, so they may have assumed based on dev filesizes it wouldn't fit in a final version.


Arcade:
  This isn't a pixel-perfect, frame accurate representation of the arcade version.  The design choices that changed were not (on the whole) changed back, so things like darkening backdrops or translucent text bubbles weren't modified.  Music and sfx are untouched.  A few minor fixes made it in though, like the blinking screen on the cabs no longer cuts off the tops of the joysticks and the images in that lower controls thing move along with the text.  Most importantly though it has full voice ;*)
  Coinage is simplified.  It should have been criminal to be able to mix n coins per credit with n credits to play.  Frankly don't understand why you'd charge more than a single coin for this anyway.

  Most if not all of the arcade's timers were actually present, initialized, and checked.  In most cases they're no longer decremented, or in the case of the name entry screen, they skip decrementing if it's at one.  Scripting for its TIME display is still present and relatively easy to hook into the existing runtime.  There's even a function that would reset the Continue counter if you inserted a coin somehow.  Implementing them was incredibly simple.
  What was not was rescripting VS to display stars for wins, disable continues, display endcards, and get the game over thing to work correctly.  Nothing, it seems, is at a sane priority level.  Carbuncle was between the boxes and stars within them.  Game over appeared between most (but not all) of the characters and their backdrops.
  Interestingly, the puyo and Carbuncle animations used on the game select screen are present, but the path the characters are supposed to follow is not.  It may not be precisely the same, but is based off a frame-by-frame capture of the original.  There's probably a much smarter way to implement that, but whatever it's done need sleep.
  The cabs are rips (0x1505D7 in mpr19534.3), but the palettes had to be rebuilt from captures.  It uses something like 4 1/2 palettes, since (see palette rant above).  One already existed in the N64 version, used for the unused, slightly clipped off joystick and button.  The one used for the screens was mutated into the one used for these blue screens and shared with the blinky ones, and the rest became their own block.  The darker palette is created from the lighter one by loading it a second time at 1/3 its brightness--awfully neat feature of the palette loading command.  The cab zoom animation is completely fudged.
  The credit & coin displays are the only really problematic elements.  They were originally printed using an 8x8 font, but 8x8 blocks are unsupported by this version's ordinary display methods.  Tacking it into the normal display stack introduces the added horror of always ensuring it's shown, even when only a specific layer should be visible.  Scripting went out the window; the whole thing was hardcoded without a look back.

  Unlike every single other version the N64 maintains the 10% "safe zone" around the edge of the screen.  The most obvious impact are the frames during gameplay, which are both unique and condensed (really miss the stone one).  There are many less obvious layout changes though, like everything in the Story Mode select menu is smooshed in eight pixels.  The single player character select pictures are a pixel or two different in size.  Lots of small weird things.


Known Issues:
  There is a known minor glitch where individual chars may appear in the upper left corner of the screen (0,0).  It occurs when something is drawn to the screen using the main scripting microcode, not the text scripting, and only while running the rest of the script prior to the "loop".  An example would be cursors in menus.  However, it may not appear as the tile being drawn due to the way image banks are assigned.
  It does occur in the unpatched version as well, but many of the loops are tighter so it's less noticable (a lot less text to display).  This can't be seen on CRTs or possibly any analog screen for what should be obvious reasons.  It would be absurd rewriting the entire tile layout system, which is pretty much the only way to fix this, so sorry if this is a gamebreaker for you.
  This is unrelated to the Korean PC release text decode errors, which is thanks to the 'switching overlay' workaround totally-not-hack for processing Shift KR externally.

  Flipped tiles still apply antialiasing, which isn't too bad.  All tile treatments do, as they share the same code used for scaling and rotating.  Flipped individual tiles also mutilate their proportions, though spans of flipped tiles do not.  My personal favorite though is how the left side of the tournament matchups applies AA twice, and the lower-left corner up to four times.  Tournament is such a hack.  Smashed more freaking bugs in there than any other part of the game.  Something up with its printer.
  I'm not rewritting DL generators to try to fix this.  It just isn't that big a deal compared to the headache sorting it all out.

  Mission mode messages do not depluralize in the ridiculous situation you're asked for a chain of one.
  It can be done, don't get me wrong.  It's just that the conditional that would have to be inserted to print one blasted letter is most of the length of the message itself, compounded by any necessary gramatical changes.  It's a lot of wasted space, and a logical mistake anyway.  A "chain of one" is not even a chain, just a spare link.  As for the other obvious route, I'm not about to create a whole additional set of messages of the likes "Match absolutely anything because the game rolled a one."  The lower range calc is shared with endless mode, so you'd be spinning off new code for a silly conditional.  Whatever.  It isn't fixed.  Eat your engrish and like it.

-Aegh
